﻿/**
* @author	:com.nickro
* @USAGE	:加载容器,可直接在场景中放置一空MC，链接本类，则可实现加载操作。
			 contain表示此容器是否添加被加载的内容.
			 监听加载过程使用addEventListener(LoadEvent.PROGRESS,FUNCTION);
			 监听加载完毕使用addEventListener(LoadEvent.COMPLETE,FUNCTION);
* @Expand	:_replace 替换 
			当contain = true时,前一个content未加载完(添加),再另外添加一个content,
			 则要求前一content连同progressBar一同移除
			 * 1、通过LoadManager来控制顺序加载,具体的思路为:LoadBox含有start&close公共方法,
			 LoadManager对LoadBox进行控制.
			 * 2、
*/

package org.nickro.controls{
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	
	import org.nickro.events.LoadEvent;
	import org.nickro.utils.LoadManager;
	public class LoadBox extends Sprite
	{
		private var _url:String ;
		private var loader:Loader;
		
		private var _contain:Boolean = true;
		private var _console:Boolean = true;
		private var _replace:Boolean = false
		private var isLoading:Boolean = false;
		public function LoadBox()
		{
			
		}
		/**
		 * 加载函数
		 * @param  url		加载文件URL地址
		 * @param  loadMode 加载模式,默认为none,无加载模式,对加载操作不进行任何处理
		 * 							line，顺序加载模式,加载完一个后再加载另一个
		 * 
		 * problems 是否需要唯一的UID
		 * 
		 */
		public function loadSwf(url:String,loadMode:String = "none"):void
		{
			_url = url;
			loader = new Loader();
			/**
			 * loadMode 加载模式
			 * none为无模式  	只加载单一url
			 * line为顺序模式	加载一组url，加载完一个后再加载另一个
			 * whole为
			 */
			if(loadMode == "none")start();
			if(loadMode == "line")
			{
				LoadManager.getInstance().addLoadBox(this,url);
			}
		}
		
		/**
		 *	停止加载操作
		 */
		public function stop():void
		{
			deleteEventListener(loader.contentLoaderInfo);
			loader.close();
		}
		
		/**
		 * 恢复加载操作
		 */
		public function start():void
		{
			loader.load(new URLRequest(_url));
			configEventListener(loader.contentLoaderInfo);
		}
		
		private function configEventListener(dispatcher:IEventDispatcher):void
		{
			dispatcher.addEventListener(ProgressEvent.PROGRESS,onProgress);
			dispatcher.addEventListener(Event.COMPLETE,onComplete);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
			dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecError);
		}
		
		private function deleteEventListener(dispatcher:IEventDispatcher):void
		{
			dispatcher.removeEventListener(ProgressEvent.PROGRESS,onProgress);
			dispatcher.removeEventListener(Event.COMPLETE,onComplete);
			dispatcher.removeEventListener(IOErrorEvent.IO_ERROR,onIOError);
			dispatcher.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecError);
		}
		
		private function onProgress(e:ProgressEvent):void
		{
			var percent:int = int((e.bytesLoaded/e.bytesTotal)*100);
			if(_console) {trace(percent)};
			dispatchEvent(new LoadEvent(LoadEvent.PROGRESS,percent));
		}
		private function onComplete(e:Event):void
		{
			isLoading = false;
			var content:* = e.target.content;
			
			if(_contain){
				if(_replace)
				{
					
				}
				if(this.numChildren > 0)
				{
					removeChildAt(0);
				}
				addChild(content);
			}
			dispatchEvent(new LoadEvent(LoadEvent.COMPLETE,content));
			deleteEventListener(e.currentTarget as LoaderInfo);
			if(_console)
			{
				trace( '"' + _url + '"'+ " :: has loaded");
				trace(this + "'numChildren :: " + this.numChildren);
			}
		}
		
		private function onIOError(e:IOErrorEvent):void
		{
			throw new IOError('"' + _url + '"'+ " is not existed");
		}
		
		private function onSecError(e:SecurityErrorEvent):void
		{
			throw new SecurityError(this + "安全问题");
		}
		/**
		* Flag to addChild 'content' in this or not
		* @param   value 	Boolean   Flag to addChild 'content' in this or not .Default Value :: true
 		*/
		public function set contain(value:Boolean):void
		{
			_contain = value;
		}
		/**
		* Flag to trace Info or not. Default Value :: true
		*/
		public function set console(value:Boolean):void
		{
			_console = value;
		}
		/**
		* @USED on the condition of (contain = true);
		* Flag to use nowContent to replace prevContent when prevContent is loading.Default Value :: false
		*/
		public function set replace(value:Boolean):void
		{
			if(_contain)
			{
				_replace = value;
			}
		}
	}
}

class LoadMode{
	public static var LINE:String = "line";
	public static var NONE:String = "none";
}